/// <reference lib="webworker" />

interface MessageEventData {
  id: string; // 文件唯一 ID
  arrayBuffer: ArrayBuffer;
  password: string;
  filename: string;
}


self.addEventListener("message", async (e: MessageEvent<MessageEventData>) => {
  const { arrayBuffer, password,  id } = e.data;
    const allfilename = id.split('-').shift()!
    const filename = allfilename.split('.').shift()!
  try {
    const encryptedBuffer = await encryptFile(arrayBuffer, password, allfilename);
    self.postMessage({ id, arrayBuffer:encryptedBuffer,filename });
  } catch (err) {
    self.postMessage({ id, error: (err as Error).message });
  }
});

/**
 * 加密文件，IV 存入元数据
 */
async function encryptFile(arrayBuffer: ArrayBuffer, password: string, allfilename: string) {
  const encoder = new TextEncoder();

  // 1. 密码派生为 256 位 AES 密钥
  const passwordData = encoder.encode(password);
  const hashBuffer = await crypto.subtle.digest("SHA-256", passwordData); // 32 字节
  const key = await crypto.subtle.importKey(
    "raw",
    hashBuffer,
    { name: "AES-GCM" },
    false,
    ["encrypt", "decrypt"]
  );

  // 2. 生成随机 IV
  const iv = crypto.getRandomValues(new Uint8Array(12));

  // 3. 构造元数据（包含 IV）
  const meta = {
    filename:allfilename.split('.').shift(),
    ext: allfilename.split(".").pop() || "",
    algo: "AES-GCM",
    iv: Array.from(iv) // 存为数组，方便 JSON 序列化
  };
  const metaStr = JSON.stringify(meta);
  const metaBuffer = encoder.encode(metaStr);
  const metaLength = new Uint32Array([metaBuffer.byteLength]); // 4 字节存长度

  // 4. 加密文件内容
  const encryptedBuffer = await crypto.subtle.encrypt(
    { name: "AES-GCM", iv },
    key,
    arrayBuffer
  );

  // 5. 拼接最终 Buffer: [metaLength(4)][metaBuffer][encryptedBuffer]
  const finalBuffer = new Uint8Array(4 + metaBuffer.byteLength + encryptedBuffer.byteLength);
  finalBuffer.set(new Uint8Array(metaLength.buffer), 0);             // 写 meta 长度
  finalBuffer.set(metaBuffer, 4);                                     // 写 meta
  finalBuffer.set(new Uint8Array(encryptedBuffer), 4 + metaBuffer.byteLength); // 写密文

  return finalBuffer.buffer;
}